namespace MBA.FluentExt.Ext
{
	public abstract class AdvancedButton<T> : AdvancedBoxComponent<T>
		where T : ExtObject
	{
		#region Properties

		/// <summary>
		/// If this button has a menu, this event fires when it is hidden 
		/// Javascript function arguments:
		/// this (Button): 
		/// menu (Menu): 
		/// </summary>
		public static Event MenuHide
		{
			get { return new Event("menuhide"); }
		}

		/// <summary>
		/// If this button has a menu, this event fires when it is shown 
		/// Javascript function arguments:
		/// this (Button): 
		/// menu (Menu): 
		/// </summary>
		public static Event MenuShow
		{
			get { return new Event("menushow"); }
		}

		/// <summary>
		/// If this button has a menu, this event fires when the mouse leaves the menu triggering element 
		/// Javascript function arguments:
		/// this (Button): 
		/// menu (Menu): 
		/// e (EventObject): 
		/// </summary>
		public static Event MenuTriggerOut
		{
			get { return new Event("menutriggerout"); }
		}

		/// <summary>
		/// If this button has a menu, this event fires when the mouse enters the menu triggering element 
		/// Javascript function arguments:
		/// this (Button): 
		/// menu (Menu): 
		/// e (EventObject): 
		/// </summary>
		public static Event MenuTriggerOver
		{
			get { return new Event("menutriggerover"); }
		}

		/// <summary>
		/// Fires when the mouse exits the button 
		/// Javascript function arguments:
		/// this (Button): 
		/// e (Event): The event object 
		/// </summary>
		public static Event MouseOut
		{
			get { return new Event("mouseout"); }
		}

		/// <summary>
		/// Fires when the mouse hovers over the button 
		/// Javascript function arguments:
		/// this (Button): 
		/// e (Event): The event object 
		/// </summary>
		public static Event MouseOver
		{
			get { return new Event("mouseover"); }
		}

		/// <summary>
		/// Fires when the 'pressed' state of this button changes (only if enableToggle = true) 
		/// Javascript function arguments:
		/// this (Button): 
		/// pressed (Boolean): 
		/// </summary>
		public static Event Toggle
		{
			get { return new Event("toggle"); }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// False to not allow a pressed Button to be depressed (defaults to undefined). Only valid when enableToggle is true. 
		/// </summary>
		public T AllowDepress(bool allowDepress)
		{
			return Config<T>("allowDepress", allowDepress);
		}

		/// <summary>
		/// (Optional) The side of the Button box to render the arrow if the button has an associated menu. Two values are allowed: 'right' 'bottom' Defaults to 'right' . 
		/// </summary>
		public T ArrowAlign(ArrowAlignment arrowAlign)
		{
			return Config<T>("arrowAlign", arrowAlign);
		}

		/// <summary>
		/// By default, if a width is not specified the button will attempt to stretch horizontally to fit its content. If the button is being managed by a width sizing layout (hbox, fit, anchor), set this to false to prevent the button from doing this automatic sizing. Defaults to undefined. 
		/// </summary>
		public new T AutoWidth(bool autoWidth)
		{
			return base.AutoWidth(autoWidth);
		}

		/// <summary>
		/// (Optional) A DomQuery selector which is used to extract the active, clickable element from the DOM structure created. When a custom template is used, you must ensure that this selector results in the selection of a focussable element. Defaults to 'button:first-child' . 
		/// </summary>
		public T ButtonSelector(string buttonSelector)
		{
			return Config<T>("buttonSelector", buttonSelector);
		}

		/// <summary>
		/// The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu). Defaults to 'click'. 
		/// </summary>
		public T ClickEvent(Event clickEvent)
		{
			return Config<T>("clickEvent", clickEvent);
		}

		/// <summary>
		/// A CSS class string to apply to the button's main element. 
		/// </summary>
		public new T Cls(string cls)
		{
			return base.Cls(cls);
		}

		/// <summary>
		/// True to enable pressed/not pressed toggling (defaults to false) 
		/// </summary>
		public T EnableToggle(bool enableToggle)
		{
			return Config<T>("enableToggle", enableToggle);
		}

		/// <summary>
		/// False to disable visual cues on mouseover, mouseout and mousedown (defaults to true) 
		/// </summary>
		public T HandleMouseEvents(bool handleMouseEvents)
		{
			return Config<T>("handleMouseEvents", handleMouseEvents);
		}

		/// <summary>
		/// A function called when the button is clicked (can be used instead of click event). The handler is passed the following parameters: b : ButtonThis Button. e : EventObjectThe click event. 
		/// </summary>
		public T Handler(Raw handler)
		{
			return Config<T>("handler", handler);
		}

		/// <summary>
		/// True to start hidden (defaults to false) 
		/// </summary>
		public new T Hidden(bool hidden)
		{
			return base.Hidden(hidden);
		}

		/// <summary>
		/// A css class which sets a background image to be used as the icon for this button 
		/// </summary>
		public T IconCls(string iconCls)
		{
			return Config<T>("iconCls", iconCls);
		}

		/// <summary>
		/// Standard menu attribute consisting of a reference to a menu object, a menu id or a menu config blob (defaults to undefined). 
		/// </summary>
		public T Menu(IMenu menu)
		{
			return Config<T>("menu", menu);
		}

		/// <summary>
		/// Standard menu attribute consisting of a reference to a menu object, a menu id or a menu config blob (defaults to undefined). 
		/// </summary>
		public T Menu(string menuId)
		{
			return Config<T>("menu", menuId);
		}

		/// <summary>
		/// The position to align the menu to (see Ext.Element.alignTo for more details, defaults to 'tl-bl?'). 
		/// </summary>
		public T MenuAlign(string menuAlign)
		{
			return Config<T>("menuAlign", menuAlign);
		}

		/// <summary>
		/// The minimum width for this button (used to give a set of buttons a common width). See also Ext.Panel. minButtonWidth . 
		/// </summary>
		public T MinWidth(uint minWidth)
		{
			return Config<T>("minWidth", minWidth);
		}

		/// <summary>
		/// If used in a Toolbar, the text to be used if this item is shown in the overflow menu. See also Ext.Toolbar.Item. overflowText . 
		/// </summary>
		public T OverflowText(string overflowText)
		{
			return Config<T>("overflowText", overflowText);
		}

		/// <summary>
		/// True to start pressed (only if enableToggle = true) 
		/// </summary>
		public T Pressed(bool pressed)
		{
			return Config<T>("pressed", pressed);
		}

		/// <summary>
		/// True to repeat fire the click event while the mouse is down. This can also be a ClickRepeater config object (defaults to false). 
		/// </summary>
		public T Repeat(bool repeat)
		{
			return Config<T>("repeat", repeat);
		}

		/// <summary>
		/// True to repeat fire the click event while the mouse is down. This can also be a ClickRepeater config object (defaults to false). 
		/// </summary>
		// TODO: ClickRepeater object
		//public T Repeat(Util.ClickRepeater repeat)
		//{
		//	return Config<T>("repeat", repeat);
		//}
		/// <summary>
		/// (Optional) The size of the Button. Three values are allowed: 'small'Results in the button element being 16px high. 'medium'Results in the button element being 24px high. 'large'Results in the button element being 32px high. Defaults to 'small' . 
		/// </summary>
		public T Scale(ButtonScale scale)
		{
			return Config<T>("scale", scale);
		}

		/// <summary>
		/// The scope ( this reference) in which the handler and toggleHandler is executed. Defaults to this Button. 
		/// </summary>
		public T Scope(Raw scope)
		{
			return Config<T>("scope", scope);
		}

		/// <summary>
		/// Set a DOM tabIndex for this button (defaults to undefined) 
		/// </summary>
		public T TabIndex(int tabIndex)
		{
			return Config<T>("tabIndex", tabIndex);
		}

		public new Button ToBasic()
		{
			return new Button { configDictionary = configDictionary };
		}

		/// <summary>
		/// A Template used to create the Button's DOM structure. Instances, or subclasses which need a different DOM structure may provide a different template layout in conjunction with an implementation of getTemplateArgs. 
		/// </summary>
		// TODO: Template object
		//public T Template(Template template)
		//{
		//	return Config<T>("template", template);
		//}
		/// <summary>
		/// The group this toggle button is a member of (only 1 per group can be pressed) 
		/// </summary>
		public T ToggleGroup(string toggleGroup)
		{
			return Config<T>("toggleGroup", toggleGroup);
		}

		/// <summary>
		/// Function called when a Button with enableToggle set to true is clicked. Two arguments are passed: button : Ext.Buttonthis Button object state : BooleanThe next state of the Button, true means pressed. 
		/// </summary>
		public T ToggleHandler(Raw toggleHandler)
		{
			return Config<T>("toggleHandler", toggleHandler);
		}

		/// <summary>
		/// The type of tooltip to use. Either 'qtip' (default) for QuickTips or 'title' for title attribute. 
		/// </summary>
		public T TooltipType(TooltipType tooltipType)
		{
			return Config<T>("tooltipType", tooltipType);
		}

		#endregion Methods
	}

	public class AdvancedButton : AdvancedButton<AdvancedButton>
	{
		protected override string ExtNamespace
		{
			get { return "Ext.Button"; }
		}

	}

	public abstract class Button<T> : BoxComponent<T>
		where T : ExtObject
	{
		#region Properties

		/// <summary>
		/// Fires when this button is clicked 
		/// Javascript function arguments:
		/// this (Button): 
		/// e (EventObject): The click event 
		/// </summary>
		public static Event Click
		{
			get { return new Event("click"); }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// True to start disabled (defaults to false) 
		/// </summary>
		public new T Disabled(bool disabled)
		{
			return base.Disabled(disabled);
		}

		// TODO: make an enum like Coolite
		/// <summary>
		/// The path to an image to display in the button (the image will be set as the background-image CSS property of the button by default, so if you want a mixed icon/text button, set cls:'x-btn-text-icon') 
		/// </summary>
		public T Icon(string icon)
		{
			return Config<T>("icon", icon);
		}

		/// <summary>
		/// (Optional) The side of the Button box to render the icon. Four values are allowed: 'top' 'right' 'bottom' 'left' Defaults to 'left' . 
		/// </summary>
		public T IconAlign(IconAlignment iconAlign)
		{
			return Config<T>("iconAlign", iconAlign);
		}

		/// <summary>
		/// The button text to be used as innerHTML (html tags are accepted) 
		/// </summary>
		public T Text(string text)
		{
			return Config<T>("text", text);
		}

		public new AdvancedButton ToAdvanced()
		{
			return new AdvancedButton { configDictionary = configDictionary };
		}

		/// <summary>
		/// The tooltip for the button - can be a string to be used as innerHTML (html tags are accepted) or QuickTips config object 
		/// </summary>
		public T Tooltip(string tooltip)
		{
			return Config<T>("tooltip", tooltip);
		}

		/// <summary>
		/// The tooltip for the button - can be a string to be used as innerHTML (html tags are accepted) or QuickTips config object 
		/// </summary>
		// TODO: QuickTip object
		//public T Tooltip(QuickTip tooltip)
		//{
		//	return Config<T>("tooltip", tooltip);
		//}
		/// <summary>
		/// submit, reset or button - defaults to 'button' 
		/// </summary>
		public T Type(ButtonType type)
		{
			return Config<T>("type", type);
		}

		#endregion Methods
	}

	public class Button : Button<Button>
	{
		protected override string ExtNamespace
		{
			get { return "Ext.Button"; }
		}

	}
}